package com.rainng.coursesystem.service;

import com.rainng.coursesystem.model.HomeworkItem;
import com.rainng.coursesystem.model.MutualItem;
import com.rainng.coursesystem.model.SubmitHomeworkItem;
import com.rainng.coursesystem.repository.HomeworkRepository;
import com.rainng.coursesystem.repository.MutualRepository;
import com.rainng.coursesystem.repository.StudentRepository;
import com.rainng.coursesystem.repository.SubmitHomeworkRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class HomeworkService {

    @Autowired
    private HomeworkRepository HomeworkRepository;

    @Autowired
    private SubmitHomeworkRepository SubmitHomeworkRepository;

    @Autowired
    private StudentRepository StudentRepository;

    @Autowired
    private MutualRepository MutualRepository;


    String currentDir = System.getProperty("user.dir");
    private String uploadDir= currentDir + "\\src\\main\\resources\\homework";


    // 教师发布作业
    public String TeacherPublishHomework(MultipartFile file, Long courseId, String title, String text, Date deadLine) throws Exception {
        // 使用 UUID 生成唯一的作业 ID
        UUID newHomeworkId = UUID.randomUUID();
        // 定义文件的存储路径
        Path dirPath = Paths.get(uploadDir, String.valueOf(newHomeworkId));
        Files.createDirectories(dirPath);
        Path copyLocation = Paths.get(dirPath.toString(),file.getOriginalFilename());// 确保目录存在
        Files.copy(file.getInputStream(), copyLocation);
        HomeworkItem item = new HomeworkItem();
        item.setHomeworkId(newHomeworkId);
        item.setFileName(file.getOriginalFilename());
        item.setFileData(dirPath.toString());
        item.setCourseId(courseId);
        item.setTitle(title);
        item.setText(text);
        item.setDeadLine(deadLine);
        item.setIsMutual("false");
        HomeworkRepository.save(item);
        return "homework uploaded and added successfully!";
    }

    public List<HomeworkItem> listHomework(Long courseId) {
        return HomeworkRepository.findAllByCourseId(courseId);
    }



    public String studentSubmitHomework(MultipartFile file, UUID homeworkId, long userId,String path) throws IOException {

        Path copyLocation = Paths.get(path, homeworkId.toString() + "_" + file.getOriginalFilename());
        Files.createDirectories(copyLocation.getParent());  // 确保目录存在
        Files.copy(file.getInputStream(), copyLocation);
        String userName;
        LocalDateTime localDateTime = LocalDateTime.now();
        userName=StudentRepository.findUserNameById(userId);
        // 将本地时间转换为带时区的日期时间
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        Date date = Date.from(zonedDateTime.toInstant());
        Optional<SubmitHomeworkItem> existingItem = SubmitHomeworkRepository.findByUserIdAndHomeworkId(userId, homeworkId);
        SubmitHomeworkItem item;
        if (existingItem.isPresent()) {
            item = existingItem.get();
    }
        else{
            item= new SubmitHomeworkItem();
            item.setHomeworkId(homeworkId);
            item.setUserId(userId);
            UUID newStudentHomeworkId = UUID.randomUUID();
            item.setStudentHomeworkId(newStudentHomeworkId);
        }
        item.setSubmissionTime(date);
        item.setFileName(file.getOriginalFilename());
        item.setFileData(copyLocation.toString());
        item.setUserName(userName);
        SubmitHomeworkRepository.save(item);
        return "homework submitted successfully!";
    }

    public List<SubmitHomeworkItem> listSubmittedHomework(UUID homeworkId) { //教师端通过作业id查看所有作业
        return SubmitHomeworkRepository.findAllByHomeworkId(homeworkId);
    }
    public HomeworkItem getHomeworkById(UUID homeworkId) {
        return HomeworkRepository.findById(homeworkId).orElse(null);
    }

    public SubmitHomeworkItem listSubmittedHomeworkByUserId(UUID homeworkId, long userId) {
        return SubmitHomeworkRepository.findAllByHomeworkIdAndUserId(homeworkId,userId);
    }

    public SubmitHomeworkItem getStudentHomeworkById(UUID StudentHomeworkId) {
        return SubmitHomeworkRepository.findById(StudentHomeworkId).orElse(null);
    }

    public MutualItem getById(UUID StudentHomeworkId,Long userId) {
        String userName=StudentRepository.findUserNameById(userId);
        return MutualRepository.findByStudentHomeworkIdAndAndMutualName(StudentHomeworkId,userName);
    }

    public void setSorce(SubmitHomeworkItem item) {
        SubmitHomeworkRepository.save(item);
    }



    public String publishPeerReview(UUID homeworkId, Date endDate, int reviewCount) {
        List<SubmitHomeworkItem> items = SubmitHomeworkRepository.findAllByHomeworkId(homeworkId);
        HomeworkItem item = HomeworkRepository.findById(homeworkId).orElse(null);
        item.setIsMutual("true");
        HomeworkRepository.save(item);
        Set<String> uniqueUsernamesSet = items.stream()
                .map(SubmitHomeworkItem::getUserName)
                .collect(Collectors.toSet());
        List<String> uniqueUsernames = new ArrayList<>(uniqueUsernamesSet);
        int size=uniqueUsernames.size();
        List<int[]> mutualPair = generateRandomFilledSquare(size,reviewCount);
        List<MutualItem> mutualItems = new ArrayList<>();
        List<UUID> sequenceList = new ArrayList<>();
        for(int j=0;j<size;j++) {
            sequenceList.add(items.get(j).getStudentHomeworkId());
            System.out.println(items.get(j).getStudentHomeworkId());
            System.out.println(reviewCount*size);
        }
        for(int i=0;i<reviewCount*size;i++) {
                int[] pair = mutualPair.get(i);
                MutualItem mutualItem=new MutualItem();
                mutualItem.setStudentHomeworkId(sequenceList.get(pair[0]-1));
                mutualItem.setEndTime(endDate);
                mutualItem.setMutualName(uniqueUsernames.get(pair[1]-1));
                mutualItem.setHomeworkId(homeworkId);
                mutualItems.add(mutualItem);
        }
        MutualRepository.saveAll(mutualItems);
        return "homework submitted successfully!";
    }

    public static List<int[]> generateRandomFilledSquare(int n, int y) {
        if (y > n - 1) {
            throw new IllegalArgumentException("y cannot be greater than n-1 when diagonal is excluded");
        }

        Random random = new Random();
        List<int[]> filledCoordinates = new ArrayList<>();
        boolean[][] filled = new boolean[n][n];

        // Initialize counters for rows and columns
        int[] rowCount = new int[n];
        int[] colCount = new int[n];

        // Try to fill the square randomly until a valid configuration is found
        while (true) {
            // Reset the counters and filled array
            Arrays.fill(rowCount, 0);
            Arrays.fill(colCount, 0);
            for (int i = 0; i < n; i++) {
                Arrays.fill(filled[i], false);
            }

            // Randomly fill the square
            filledCoordinates.clear();
            for (int i = 0; i < n * y; i++) {
                int row, col;
                do {
                    row = random.nextInt(n);
                    col = random.nextInt(n);
                } while (filled[row][col] || row == col || rowCount[row] >= y || colCount[col] >= y);

                filled[row][col] = true;
                rowCount[row]++;
                colCount[col]++;
                filledCoordinates.add(new int[]{row + 1, col + 1}); // Adding 1 to convert from 0-based to 1-based index
            }

            // Check if the constraints are satisfied
            boolean valid = true;
            for (int i = 0; i < n; i++) {
                if (rowCount[i] != y || colCount[i] != y) {
                    valid = false;
                    break;
                }
            }
            if (valid) {
                break; // Found a valid configuration
            }
        }

        return filledCoordinates;
    }

    public void setMutualSorce(MutualItem item) {
        MutualRepository.save(item);
    }

    public List<MutualItem> listSubmittedHomeworkByHomeworkId(UUID studentHomeworkId) {
        return MutualRepository.findAllByStudentHomeworkId(studentHomeworkId);
    }

    public List<MutualItem> listSubmittedHomeworkByuserkId(Long userId,UUID homeworkId) {
        String userName=StudentRepository.findUserNameById(userId);
        return MutualRepository.findAllByMutualNameAndHomeworkId(userName,homeworkId);
    }
}
